/*
	Credits:
	Vern for a lot of code and inspiration, http://vern.com/mwtools/
	F.M. for code to handle mw-friends only.
	Max Power for the loot logging code.
	
	Changelog:
	2009-10-22	Quick hack to support the apps.new.facebook.com
	2009-11-01	v1.06 beta Removed base64 coding for specials
	2009-12-16	Chrome fixed and other stuff.
	2010-01-06	Rewritten version to do Ajax calls instead of xmlhttp
	2010-03-20	Added the search for completed Chop Shops
	2010-03-27	Added robbery mastery bonus.
	2010-04-08	Added the Weapons Depots completed bonus.
				Added Pistol Pete awesome FQL query for finding MW friends.
	
	
*/

javascript:(function (){
var version='Collect Boosts v1.11 beta (ajax)';
try {
	if (document.getElementById('app10979261223_iframe_canvas')) {
		if(confirm('You need to break out the mw-frame first.\nPress OK to do it now.')) {
			window.location.href=document.getElementById('app10979261223_iframe_canvas').src;
			return;
		}
	}
	else if (document.getElementsByClassName('canvas_iframe_util')[0]) {
		if(confirm('You need to break out the mw-frame first.\nPress OK to do it now.')) {
			window.location.href=document.getElementsByClassName('canvas_iframe_util')[0].src;
			return;
		}
	}
	else {
		document.body.parentNode.style.overflowY="scroll";
		document.body.style.overflowX="auto";
		document.body.style.overflowY="auto";
		try { 
			if(typeof FB != 'undefined') {
				FB.CanvasClient.stopTimerToSizeToContent; 
				window.clearInterval(FB.CanvasClient._timer);
				FB.CanvasClient._timer=-1;
			}
			document.getElementById('mw_zbar').innerHTML='';
		}
		catch (fberr) {}
	}
	// from Yevgen Silant'yev, http://joyka.pp.ua/
	function getMWURL() {
		str = document.location;
		str = str.toString();
		beg = str.substring(0,str.indexOf('?')+1);
		str = str.substring(str.indexOf('?')+1);
		str = str.split('&');
		mid = '';
		for(var i=0;i<str.length;i++){
			if(str[i].indexOf('sf_xw_')==0){ mid=mid+str[i]+'&'; }
		}
		return beg+mid;
	}
	if (navigator.appName == 'Microsoft Internet Explorer') { 
		alert('You are using Internet Explorer, this bookmarklet will not work.\nUse Firefox or Chrome instead.');
		return;
	}
	var MWURL = getMWURL();
	var sf_xw_sig = /sf_xw_sig=([a-fA-F0-9]+)/.exec(MWURL);
	var run=1,xmlHTTP,content=document.getElementById('content_row'),debug=false,specialmsg='',output='',
	x=0,second=false,last_url=null,retries=0,tmpkey=false,totalfriends=0,combinedloot='',done=0,list=0,ach=1,
	mw_url='http://apps.facebook.com/inthemafia/profile.php?id=%7B%22user%22%3A%22ID%22%7D',color='#BCD2EA',
	fb_url='http://www.facebook.com/profile.php?id=',friends_helped=0;
	var wait1=3,wait2=6,skip=0;
	var log_size=20;
	var log_keep=/(Limit|friends|Facebook|Starting)/;
	var callmade = false;
	var falsechecks = 0;
	var boost='';
	var newfriends=[],newnames=[],friendslist=[],nameslist=[],friendarray=[],friendsint=[],namesint=[],names=[];
	var currentPageCount = 1;
	try {
		//Gift page friends from Francisco Moraes
		var inputs = document.getElementsByTagName("input");
		var c = 0;
		for(i = 0; i < inputs.length; i++) {
			var input = inputs[i];
			if(input.id.indexOf("cb_recip_") == 0) {
				friendsint[c] = input.id.substring(9);
				namesint[c] = input.nextSibling.nodeValue.replace(/^\s+|\s+$/g, '') ;
				c++;
			}
		}
		friends = friendsint;
		names = namesint;
		//alert('Internal friends: '+friends.length+' Names collected: '+names.length);
	}
	catch (interror) { alert(interror); }
	if (friendsint.length > 0) { 
		list=0; 
		specialmsg = '<tr><td colspan="3"><span class="energy_highlight">Found '+friendsint.length+' mafia members.<br />You can only help FB friends so this list could give a lot of not friend errors.</span><br /><span class="bad">Recommendation: Use the Manual list if you have a large non FB-friend mafia.</span></td></tr>';
	}
	if (friendsint.length == 0) { 
		list=1; 
		specialmsg = '<tr><td colspan="3"><span class="bad">No Friends found!</span> <span class="energy_highlight">You have to use the Manual List. Run the bookmarklet on your Gift page to find mafia members.</span><br /><span>You can also try <a id="loadfriendslnk" href="#">clicking here</a>. Wait a while and see if Facebook can help you populate the list.<br />You may need to click a few times.</span></td></tr>';
	}
	// createCookie from Vern's Toolkit http://vern.com/mwtools/
	function createCookie(name,value) {
		// expire one month from now
		var expires = new Date();
		expires.setDate(expires.getDate()+30);
		document.cookie = name+"="+value+";expires="+expires.toGMTString()+"; path=/";
	}

	// readCookie from Vern's Toolkit http://vern.com/mwtools/
	function readCookie(name) {
		var i,
			cookie,
			nameEQ = name+"=",
			cookieArray = document.cookie.split(";");
		for (i=0; i< cookieArray.length; i++) {
			cookie = cookieArray[i];
			while (cookie.charAt(0)==' ')
				cookie = cookie.substring(1,cookie.length);
			if (cookie.indexOf(nameEQ) == 0)
				return cookie.substring(nameEQ.length,cookie.length);
		}
		return null;
	}

	//Pistol Pete FQL code
	function loadfbfriends(friends) {
		var friendquicklist='';
		for(i = 0; i < friends.length; i++) {
			if (friends[i].name != null) {
			friendquicklist += friends[i].id+', '+ friends[i].name.replace(/[^A-Za-z0-9 ]/g, '') +'\n';
			}
		}
		document.getElementById('friendlist').value = friendquicklist;
	}
	function parseFBFr(){
		var fql="SELECT uid,name FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=" + FB.Facebook.apiClient.get_session().uid + ") AND is_app_user = 1 ORDER BY name";
		//alert(fql);
		var f=function(){
			var results=[];
			return {
				getResults: function(){ return results; },
				process: function(fbfr){
					for(i=0;i<fbfr.length;i++) {
						  results[results.length]={	'id':fbfr[i].uid, 'name':fbfr[i].name };
					}
					friends=results;
				}
			};
		}();
		FB.Facebook.apiClient.fql_query(fql, f.process);
		return friends;
	}
	
	//wait1 = readCookie('spockjobs_wait1');
	//if (wait1) wait1=wait1.replace(/[^0-9]/g,'');
	if ((wait1 == null) || (wait1.length == 0)) { wait1 = 3; }
	//wait2 = readCookie('spockjobs_wait2');
	//if (wait2) wait2=wait2.replace(/[^0-9]/g,'');
	if ((wait2 == null) || (wait2.length == 0)) { wait2 = 6; }
	//skip = readCookie('spockjobs_skip');
	//if (skip) skip=skip.replace(/[^0-9]/g,'');
	if ((skip == null) || (skip.length == 0)) { skip = 0; }
	redo="";

	function myRandom(min,max) {
		return min + Math.floor(Math.round((Math.random() * (max - min))));
	}
	// deliberate pause from Vern's toolkit.js, http://vern.com/mwtools/
	// given a number of seconds, an optional message and a resume
	// function, will pause a few seconds and then execute the function
	function pausing(seconds,message,resume_func) {
		// if the message was left out, shuffle things a bit
		if (typeof(message) == 'function') {
			resume_func = message;
			message = null;
		}
		if (message)
			message=message;
		else
		message='Pausing';
		msg(message+' <span id="seconds">'+seconds+' second'+(seconds==1?'':'s')+'</span>...');
		//var me = this;
		var timer = setInterval(function(){//)
			seconds--;
			if (document.getElementById('seconds'))
				document.getElementById('seconds').innerHTML=seconds+' second'+(seconds==1?'':'s');
			else
				clearInterval(timer);
			if (seconds<=0) {
				clearInterval(timer);
				if (typeof(resume_func) == 'function')
					resume_func();
			}
		},1000);
	}

	redo="";
	//logging="";
	//selectableboosts = ['Level','Iced','Achievement','Stash'];
	selectableboosts = ['Level','Iced','Chop','Weapons','Robbery','Achievement'];
	var config_html =
	'<style type="text/css">'+
		'.messages img{margin:0 3px;vertical-align:top};'+
		'#close{display:inline};'+	
	'</style>'+
	'<form name="spockform">'+
		'<table class="messages">'+
			'<tr><td colspan="3"><span class="good">We recommend you use <a href="http://www.spockholm.com/mafia/testing.php?CollectBoosts">Brutus Helper</a> instead of Collect Boosts, CB is no longer being updated.</span></td></tr>'+
			'<tr><td colspan="2">Configuration</td><td align="right" style="text-align:right;font-size:0.8em;">'+version+' - <a href="http://www.spockholm.com/mafia/bookmarklets.php" target="_top">Spockholm Mafia Tools</a> - <a href="#" id="close"><img src="http://www.spockholm.com/mafia/stop.gif" title="Close" width="16" height="16"></a></td></tr>'+
			specialmsg+
			'<tr><td>Delay interval:</td><td><input type="text" name="wait1" id="wait1" value="'+wait1+'" size="3">-<input type="text" name="wait2" id="wait2" value="'+wait2+'" size="3"></td><td>Delay in seconds between checks.</td></tr>'+
			'<tr><td>Skip:</td><td><input type="text" name="skip" id="skip" value="'+skip+'" size="5"></td><td>Friends to skip</td></tr>'+
			'<tr><td valign="top">Boosts:</td><td>';
			for(var i=0;i<selectableboosts.length;i++){
				config_html += '<input type="checkbox" name="'+selectableboosts[i]+'" id="'+selectableboosts[i]+'" '+(selectableboosts[i]=='Level'?'checked':'')+'/>&nbsp;'+selectableboosts[i]+'<br />';
			}
	config_html += '</td><td colspan="2" valign="top">Select boosts to search for.<br /><span class="bad">Achievements are painfully slow and not recommended.</span></td></tr>'+
			'<tr>'+
				'<td>List: </td>'+
				'<td>'+
					'<select name="list" id="list">';
					if (list==1) {
						config_html += '<option value="1"'+(list==1?" selected":"")+'>Manual List</option>';
					}
					else {
						config_html += '<option value="0"'+(list==0?" selected":"")+'>Internal List</option>';
						config_html += '<option value="1"'+(list==1?" selected":"")+'>Manual List</option>';
					}
	config_html += '</select>'+
				'</td>'+
				'<td colspan="2"> Select which source to use to find your list of mafia.</td>'+
			'</tr>'+
			'<tr id="manual_list">'+
				'<td>Friend List:</td>'+
				'<td colspan="3"><textarea name="friendlist" id="friendlist" class="instructions" rows="15" cols="40">'+
					'Enter in this box a list of your mafia.\n'+
					'Enter an ID and (optional) Name, one per line.\n'+
					'Lines that do not begin with a number will be discarded.\n'+
					'\n'+
					'Examples:\n'+
					'123123123123,One Two Three\n'+
					'456456456 Four Five\n'+
					'7898798343\n'+
				'</textarea></td>'+
			'</tr>'+
			'<tr><td>Restart: </td><td><input type="checkbox" name="redo" id="redo" '+redo+'/></td><td colspan="2"> Restart processing from the beginning when we are done.</td>'+
			'<tr><td>Debug: </td><td><input type="checkbox" name="debug" id="debug" /></td><td colspan="2"> Output messages for debugging?</td></tr>'+
			'<tr><td colspan="3"><a class="sexy_button" id="start">Start</a></td></tr>'+
		'</table>'+
	'</form>';

	var running_html = 
	'<style type="text/css">'+
		'.messages img{margin:0 3px;vertical-align:top}'+
		'.messages input {border: 1px solid #FFF;margin 0;padding 0;background: #000; color: #FFF; width: 20px;}'+
		'#play{display:none}'+
		'#pause{display:inline}'+
		'#close{display:inline}'+
	'</style>'+
	'<table class="messages">'+
	'<tr>'+
		'<td><a href="#" id="next">Next friend</a></td><td colspan="2" style="text-align:right;">'+version+' - <a href="http://www.spockholm.com/mafia/bookmarklets.php" target="_top">Spockholm Mafia Tools</a> - <a href="#" id="play"><img src="http://www.spockholm.com/mafia/play.gif" title="Play" width="16" height="16" /></a> <a href="#" id="pause"><img src="http://www.spockholm.com/mafia/pause.gif" title="Pause" width="16" height="16" /></a> <a href="#" id="close"><img src="http://www.spockholm.com/mafia/stop.gif" title="Close" width="16" height="16" /></a></td>'+
	'</tr>'+
	'<tr>'+
		'<td width="100">Progress:</td>'+
		'<td><span id="progress"></span> &nbsp; (<a href="#" id="remaining">Popup remaining</a>)</td>'+
		'<td align="right" style="text-align:right;">Delay: <input id="delay1" name="delay1" type="text" value="'+wait1+'" maxlength="2" /> - <input id="delay2" name="delay2" type="text" value="'+wait2+'" maxlength="2" /> sec</td>'+
	'</tr>'+
	'<tr>'+
		'<td>Status:</td>'+
		'<td colspan="2" id="status"></td>'+
	'</tr>'+
	'<tr>'+
		'<td valign="top">Collected:</td>'+
		'<td colspan="2" id="loot"></td>'+
	'</tr>'+
	'<tr>'+
		'<td valign="top"><a href="#" id="logshow">Showing</a> Log:</td>'+
		'<td colspan="2" id="log" valign="top"></td>'+
	'</tr>'+
	'</table>';
	function create_div() {
		if(document.getElementById('spockdiv')) {
			document.getElementById('spockdiv').innerHTML = config_html;
		}
		else {
			var spock_div=document.createElement("div");
			spock_div.id = 'spockdiv';
			spock_div.innerHTML = config_html;
			content.insertBefore(spock_div, content.firstChild);
		}
	}
	create_div();
	
	if (friendsint.length == 0) { 	
		document.getElementById('loadfriendslnk').onclick=function(e) {
			document.getElementById("friendlist").focus();
			loadfbfriends(parseFBFr());
		};
	}	
	
	document.getElementById('close').onclick=function(e) {
		run = 0;
		delete xmlHTTP['onreadystatechange'];
		document.getElementById("content_row").removeChild(document.getElementById("spockdiv"));
		return false;
	};
	document.getElementById("list").onchange=function(e) {
		if (document.getElementById("list").value == 0) { document.getElementById("manual_list").style.display = 'none'; }
		else { document.getElementById("manual_list").style.display = 'table-row'; list=1; }
	};
	document.getElementById("list").onchange();
	document.getElementById("friendlist").onfocus=function(e) {
		document.getElementById("friendlist").value="";
		document.getElementById("friendlist").style.color="#000";
		document.getElementById("friendlist").onfocus=null;
	};
	//start start function
	//document.getElementById('start').onclick=function(e) {
	function start(){
		run = 1;
		wait1 = parseInt(document.spockform.wait1.value);
		//createCookie("spockjobs_wait1",wait1);
		wait2 = parseInt(document.spockform.wait2.value);
		//createCookie("spockjobs_wait2",wait2);
		skip = parseInt(document.spockform.skip.value);
		//createCookie("spockjobs_skip",skip);

		if (document.spockform.redo.checked) { redo = "checked"; }
		else { redo = ""; }
		if (document.spockform.debug.checked) { debug = true; }
		//make array with the valid boosts
		boosts = [];
		if (document.spockform.Level.checked) { boosts.push('Level'); }
		if (document.spockform.Iced.checked) { boosts.push('Iced'); }
		if (document.spockform.Chop.checked) { boosts.push('Chop'); }
		if (document.spockform.Weapons.checked) { boosts.push('Weapons'); }
		if (document.spockform.Robbery.checked) { boosts.push('Rob'); }
		if (document.spockform.Achievement.checked) { boosts.push('Achievement'); }
		//if (document.spockform.Stash.checked) { boosts.push('Stash'); }
		if (boosts.length == 0) { boosts = ['Level']; }
		validboosts = boosts;

		if (list == 1) {
			friendarray=document.spockform.friendlist.value.split("\n");
			for (i=0; i<friendarray.length; i++) {
				if (m=/^([0-9]+)[,\s]*(.*)$/.exec(friendarray[i])) {
					friendslist[i] = m[1];
					if (m[2]) { nameslist[i] = m[2]; }
				}
			}
			delete friendarray;
			friends = friendslist;
			names = nameslist;
		}
		if ((list == 1) && (friends.length == 8) || (friends.length == 0)) {
			alert('You did not fill in the manual list properly. It should be a list containing numbers on new lines.\nList FB friends on the testing page http://www.spockholm.com/mafia/testing.php\n will create this list for you.');
			return;
		}
		//comparing the internal and the manual lists to filter friends
		if ((friendslist.length > 0) && (friendsint.length > 0)) {
			c = 0;
			for(i = 0; i < friendslist.length; i++) {
				if(friendsint[i].indexOf(friendslist[i])) {
				//if(friendslist[i].toString() in friendsint) { 
					newfriends[c++] = friendslist[i]; 
					newnames[c] = nameslist[i]; 
				}
			}
			friends=[],names=[];
			friends = newfriends;
			names = newnames;
			//alert('Both in internal and manual friends: '+friends.length);
		}
		//clean up unused arrays
		if (newfriends.length > 0) { delete newfriends; }
		if (newnames.length > 0) { delete newnames; }
		if (friendslist.length > 0) { delete friendslist; }
		if (nameslist.length > 0) { delete nameslist; }
		if (friendsint.length > 0) { delete friendsint; }
		if (namesint.length > 0) { delete namesint; }

		document.getElementById('spockdiv').innerHTML = running_html;
		document.getElementById('next').onclick=function(e) {
			done++;
			friends=friends.slice(1);
			boosts = validboosts;
			run=1;
			document.getElementById("pause").style.display = 'none';
			document.getElementById("play").style.display = 'inline';
			search();
			return false;
		};
		// document.getElementById('debug').onclick=function(e) {
			// if (debug) { debug = false; document.getElementById('debug').innerHTML = 'Debug off'; }
			// else { debug = true; document.getElementById('debug').innerHTML = 'Debug on'; }		
		// }
		document.getElementById('pause').onclick=function(e) {
			run = 0;
			document.getElementById("pause").style.display = 'none';
			document.getElementById("play").style.display = 'inline';
			return false;
		};
		document.getElementById('play').onclick=function(e) {
			run = 1;
			document.getElementById("play").style.display = 'none';
			document.getElementById("pause").style.display = 'inline';
			msg('Resuming boost searching... (<a href="'+last_url+'">url</a>)');
			retries = 0;
			request(last_url);
			return false;
		};
		document.getElementById('close').onclick=function(e) {
			run = 0;
			delete xmlHTTP['onreadystatechange'];
			document.getElementById("content_row").removeChild(document.getElementById("spockdiv"));
			return false;
		};
		document.getElementById('delay1').onkeyup=function(e) {
			time = parseInt(document.getElementById('delay1').value);
			if((time < 0) || (!time)) { wait1 = 0; }
			else { wait1 = time; }
			//createCookie('spockaX_wait1',wait1);
			document.getElementById('delay1').value=wait1;
		};
		document.getElementById('delay2').onkeyup=function(e) {
			time = parseInt(document.getElementById('delay2').value);
			if((time < 0) || (!time)) { wait2 = 0; }
			else { wait2 = time; }
			//createCookie('spockaX_wait2',wait2);
			document.getElementById('delay2').value=wait2;
		};
		document.getElementById('logshow').onclick=function(e) {
			var row = document.getElementById("log");
			if (row.style.display == '') { 
				row.style.display = 'none'; 
				document.getElementById("logshow").innerHTML = 'Hiding';
			}
			else { 
				row.style.display = '';
				document.getElementById("logshow").innerHTML = 'Showing';
			}
			return false;
		};
		savedfiends = [];
		savedfriends = friends;
		if (skip >= friends.length -1) { skip=0; }
		if (skip > 0) {
			log(timestamp()+'Skipping '+skip+' friends of '+friends.length+'.');
			friends=friends.slice(skip);
		}
		//log(timestamp()+'Number of friends existing in both lists: '+newfriends.length);
		totalfriends = friends.length;
		document.getElementById('progress').innerHTML = done+' of '+friends.length+' &nbsp; <span class="more_in">('+(done/totalfriends*100).toFixed(1)+'%)</span>';
		log(timestamp()+'Starting check of '+friends.length+' friends.');
		document.getElementById('remaining').onclick=dirtypop;
		search();
	}
	//end start function
	document.getElementById("start").onclick=start;
	function get_xmlHTTP () {
	  if (window.XMLHttpRequest)
		return new XMLHttpRequest();
	  if (window.ActiveXObject)
		return new ActiveXObject('Microsoft.XMLHTTP');
	  return null;
	}
	xmlHTTP = get_xmlHTTP();
	if (!xmlHTTP) {
	  alert('Your browser does not support XMLHTTP.');
	  return;
	}
	function request(url) {
		if (run == 1) {
			//document.getElementById('inner_page').title = '';
			document.getElementById('inner_page').addEventListener('DOMSubtreeModified',state_change,false);
			callmade = true;
			currentPageCount = pageCount;
			do_ajax('inner_page', url, 1, 1);
			//setTimeout(state_change, 4000);
		} else {
			msg('Paused boost searching.');
		}
		last_url=url;
	}
	function search() {
		if (friends.length == 0 && redo == "") {
			msg(timestamp()+'Done checking all friends for boosts.'); 
			document.getElementById("play").style.display = 'none';
			document.getElementById("pause").style.display = 'none';
			//createCookie("spockjobs_skip",0);
			document.getElementById('inner_page').removeEventListener('DOMSubtreeModified',state_change,false);
		}
		else if (friends.length == 0 && redo == "checked") {
			friends=savedfriends;
			totalfriends=friends.length;
			done=0;
			skip=0;
			//createCookie("spockjobs_skip",skip);
			boosts=validboosts;
			log(timestamp()+'<span class="money">Starting again from the beginning.</span>');
			search();
		}
		else if (boosts.length == 0) {
			msg(timestamp()+'No more boosts to check, done.'); 
			document.getElementById("play").style.display = 'none';
			document.getElementById("pause").style.display = 'none';
		}
		else {
			function f() {
				oldboost = boost;
				boost = boosts[0];
				last_url=boost_url(boost);
				msg('Checking for '+boost+(boost=='Achievement'?ach:"")+' boost '+friends[0]+' (<a href="'+last_url+'">url</a>)');
				request(boost_url(boost));
			}
			wait = myRandom(parseInt(wait1),parseInt(wait2));
			pausing(wait,'Waiting for ',f);
		}
	}
	function dirtypop() {
		var generator=window.open('','name','height=500,width=500');
		generator.document.write('<html><head><title>Mafia remaining to check</title>');
		generator.document.write('</head><body>');
		generator.document.write('<pre>Number of friends in this list: '+friends.length+'</pre><textarea rows="20">');
		for(i = 0; i < friends.length; i++) {
			generator.document.write(friends[i]+'\n');
		}
		generator.document.write('</textarea><pre><a href="javascript:self.close()">Close</a> the popup.</pre>');
		generator.document.write('</body></html>');
		generator.document.close();
	}
	function log(s) {
		document.getElementById('delay1').value=wait1;
		document.getElementById('delay2').value=wait2;
		document.getElementById('progress').innerHTML = done+' of '+totalfriends+' &nbsp; <span class="more_in">('+(done/totalfriends*100).toFixed(1)+'%)</span>';
		var l=document.getElementById('log');
		if (s) {
			 //logtrunc(s,log_size,log_keep);
			 l.innerHTML=s+'<br />'+l.innerHTML;
		}
		document.getElementById('loot').innerHTML=combinedloot;
	}
	var Loots=new Array();
	function add_loot(s){
		var f=-1;
		for(var i=0;i<Loots.length&&f==-1;++i) {
			if(Loots[i][0]==s) { f=i; }
		}
		if(f!=-1) { Loots[f][1]++; }
		else { Loots[Loots.length]=new Array(s,1); }
		var t='';
		Loots.sort();
		for(var i=0;i<Loots.length;++i) {
			t+='<span class="good">'+Loots[i][1]+'x</span> '+Loots[i][0]+'<br />';
		}
		combinedloot=t;
	}
	function msg(s) {
			document.getElementById('status').innerHTML=s;
	}
	function commas(s) {
		while (d=/(\d+)(\d{3}.*)/.exec(s)) {
			s = d[1] + ',' + d[2];
		}
		return s;
	}
	function retry(s) {
	  if (retries > 3) {
		msg(s + ', not retrying any more.');
	  }
	  else {
			setTimeout(function(){
				retries++;
				msg(s+'; retry #'+retries+'...');
				request(last_url);
			},5000);
		}
	}
	function mwlink() {
		return '<span class="more_in">[<a href="'+mw_url.replace(/ID/,friends[0])+'">MW</a>]</span>';
	}
	function fblink() {
		return '<span class="more_in">[<a href="'+fb_url+friends[0]+'">FB</a>]</span>';
	}
	function fblink2() {
		return '<a href="'+fb_url+friends[0]+'">'+friends[0]+'</a>';
	}
	function boostlink() {
		if (oldboost == "Level") return '<span class="more_in">[<a href="'+MWURL+'xw_controller=index&xw_action=levelup_boost_claim&friend_id='+friends[0]+'&skip_interstitial=1&skip_req_frame=1">Level Boost</a>]</span>';
		if (oldboost == "Iced") return '<span class="more_in">[<a href="'+MWURL+'xw_controller=index&xw_action=iced_boost_claim&friend_id='+friends[0]+'&skip_interstitial=1&skip_req_frame=1">Iced Boost</a>]</span>';
		if (oldboost == "Achievement") return '<span class="more_in">[<a href="'+MWURL+'xw_controller=index&xw_action=ach_celeb&sharer='+friends[0]+'&aid='+eval(ach-1)+'&skip_interstitial=1&skip_req_frame=1">Achievement</a>]</span>';
		if (oldboost == "Stash") return '<span class="more_in">[<a href="'+MWURL+'xw_controller=job&xw_action=collect_loot&sharer='+friends[0]+'&skip_interstitial=1&skip_req_frame=1">Secret Stash</a>]</span>';
		if (oldboost == "Chop") return '<span class="more_in">[<a href="'+MWURL+'xw_controller=propertyV2&xw_action=cs_help_final&target='+friends[0]+'&skip_interstitial=1&building_type=11&skip_req_frame=1">Chop Shop</a>]</span>';
		if (oldboost == "Weapons") return '<span class="more_in">[<a href="'+MWURL+'xw_controller=propertyV2&xw_action=cs_help_final&target='+friends[0]+'&building_type=12&skip_interstitial=1&skip_req_frame=1">Weapons Depot</a>]</span>';
		if (oldboost == "Rob") return '<span class="more_in">[<a href="'+MWURL+'xw_controller=robbing&xw_action=mastery_bonus&target='+friends[0]+'&skip_interstitial=1&skip_req_frame=1">Robbery</a>]</span>';
	}
	function boost_url(c) {
		if (c == "Level") { return 'remote/html_server.php?xw_controller=index&xw_action=levelup_boost_claim&friend_id='+friends[0]; }
		if (c == "Iced") { return 'remote/html_server.php?xw_controller=index&xw_action=iced_boost_claim&friend_id='+friends[0]; }
		if (c == "Achievement") { return 'remote/html_server.php?xw_controller=index&xw_action=ach_celeb&sharer='+friends[0]+'&aid='+ach+'&skip_interstitial=1'; }
		if (c == "Stash") { return 'remote/html_server.php?xw_controller=job&xw_action=collect_loot&sender='+friends[0]+'&install_source=newsfeed&friend='+friends[0]; }
		if (c == "Chop") { return 'remote/html_server.php?xw_controller=propertyV2&xw_action=cs_help_final&target='+friends[0]+'&building_type=11&skip_interstitial=1'; }
		if (c == "Weapons") { return 'remote/html_server.php?xw_controller=propertyV2&xw_action=cs_help_final&target='+friends[0]+'&building_type=12&skip_interstitial=1'; }
		if (c == "Rob") { return 'remote/html_server.php?xw_controller=robbing&xw_action=mastery_bonus&target='+friends[0]+'&skip_interstitial=1'; }
	}
	// From Vern's toolkit.js, http://vern.com/mwtools/
	// log puts a message in the log array and outputs it
	// limit is how many log lines we keep (0 == infinite)
	// keep is a regex of lines that we never delete
	logs = [];
	extralog = [];
	function logtrunc(message,limit,keep) {
		logs.unshift(message);
		if (limit > 0) {
			if (logs.length>limit) {
				message=logs.pop();
				if ((keep.test) && (keep.test(message)))
						extralog.unshift(message);
			}
		}
		if ((document.getElementById('log')) && (document.getElementById('log').nodeName == 'TD')) {
			document.getElementById('log').innerHTML=logs.concat(extralog,'').join('<br/>');
		}
	}
	function timestamp() {
		now = new Date();
		var CurH = now.getHours();
		CurH = (CurH<10?"0"+CurH:CurH);
		var CurM = now.getMinutes();
		CurM = (CurM<10?"0"+CurM:CurM);
		return '<span class="more_in">['+CurH+':'+CurM+']</span> ';
	}
	
	function stats_ratios() {
		var expnow = document.getElementById('user_experience').innerHTML;
		var expnext = document.getElementById('exp_for_next_level').innerHTML;
		var energy = document.getElementById('user_energy').innerHTML;
		var stamina = document.getElementById('user_stamina').innerHTML;
		expneed = eval(expnext-expnow);
		ratiolvl=eval(expneed/energy);
		ratiolvl2=eval(expneed/stamina);
		var d = 0;
		(Math.abs(ratiolvl)<10)?(d=2):(d=0);
		(Math.abs(ratiolvl2)<10)?(d2=2):(d2=0);
		if(ratiolvl=='Infinity') { ratiolvl=0; d=0; }
		if(ratiolvl2=='Infinity') { ratiolvl2=0; d2=0; }
		document.getElementById('user_stats').getElementsByClassName('stat_title')[0].innerHTML='Exp Need: <span class="energy_highlight">'+expneed+'</span><br> (<span class="energy_highlight">'+(ratiolvl).toFixed(d)+'</span> / <img src="http://mwfb.static.zynga.com/mwfb/graphics/icon_energy_16x16_01.gif" width="12" height="12" title="Exp needed per Energy">) &nbsp; (<span class="energy_highlight">'+(ratiolvl2).toFixed(d2)+'</span> / <img src="http://mwfb.static.zynga.com/mwfb/graphics/icon_stamina_16x16_01.gif" width="12" height="12" title="Exp needed per Stamina">)';
	}
	
	function state_change() {
		//if (xmlHTTP.readyState == 4) {
			//old code if (xmlHTTP.status == 200) {
			//if (document.getElementById('inner_page').title != 'checked') {
		if(currentPageCount != pageCount) {
			currentPageCount = pageCount;
			callmade=false;
			document.getElementById('inner_page').removeEventListener('DOMSubtreeModified',state_change,false);
			stats_ratios();
			//document.getElementById('inner_page').title = 'checked';
			//according to do_ajax the page has loaded
			s='';
			m=[];
			xp=0;
			ca=0;
			loot='';
			//createCookie("spockjobs_skip",parseInt(skip+done));
			//s = xmlHTTP.responseText;
			try { 
				//s = document.getElementsByClassName('message_body')[0].innerHTML; 
				s = document.getElementById('inner_page').innerHTML; 
			}
			catch (messerr) { 
				//this is where the bookmarklet stalls 2009-12-17
				//for some reason checks load the job page without the message_body box
				msg('No boost info found? message_body was not avalible.');
				//return;
				if (debug) { log(timestamp()+'Friend caused trouble, skipping. ID: '+friends[0]+' '+mwlink()+fblink()+boostlink()); }
				done++;
				friends=friends.slice(1);
				search();
			}
			if (local_xw_sig != sf_xw_sig[1]) {
				MWURL.replace(/([a-fA-F0-9]+)/,local_xw_sig);
				sf_xw_sig[1] = local_xw_sig;
				//log(timestamp()+'Updated sig key. This should help avoid the temp-key loop.');
			}
			// if (m=/top.location..*?=.*?"(.*?)"/.exec(s)) {
				// request(m[1]);			
			// }
			// chop off the Facebook stuff from the beginning, from Vern's DoJobs http://vern.com/mwtools/
			//if (/<div id="mainDiv">/.test(s)) { s=s.substr(s.indexOf('<div id="mainDiv">')); }
			//delete xmlHTTP['onreadystatechange'];
			if (m=/You\s+(earned|gained|received|collected)\s+(some|a|an)\s+(.+?)\s+from/.exec(s)) {
				if (!loot) {
					loot = '. Loot: ';
				}
				// s.match(/You gained (some|a|an) (.+?)\./g).each(function(i) {
					// loot += i.match(/You gained (some|a|an) (.+?)\./)[2]+', ';
					// add_loot(i.match(/You gained (some|a|an) (.+?)\./)[2]);
				// });
				loot+=m[3]+', ';
				add_loot(m[3]);
				loot=loot.slice(0,loot.length-2);
			}
			else if  (m = /you were given (some|a|an) (.+?)\./.exec(s)) {
				loot+=m[2]+', ';
				add_loot(m[2]);
				loot=loot.slice(0,loot.length-2);
			}
			else if (m=/You got a bonus in celebration.*money">(R?C?)(\$[\d,]+)/.exec(s)) {
				log('Received '+m[1]+m[2]+' from '+friends[0]+' achievement '+ach);
				//if (m[3]) { addloot(m[3]); }
			}
			else if (m=/You got a bonus in celebration.*money">(R?C?)(\$[\d,]+).*>(\d+) ?Experience<\/div>/.exec(s)) {
				log('Received '+m[1]+m[2]+' and '+m[3]+' exp');
			}
			else if (/achievements up to 10 times per day/.test(s)) {
				if (debug) { console.log('Sorry, you can only celebrate friends achievements up to 10 times per day, try again tomorrow! '+boostlink()); }
				//Sorry, you can only celebrate friends' achievements up to 10 times per day, try again tomorrow!
				validboosts.splice(validboosts.indexOf(boost),1);
				timestamp();
				ach=53;
				log(timestamp()+'<span class="bad">'+boost+' boost limit reached</span>, not checking for more of those. '+boostlink());
			}
			else if (/You already got the bonus before/.test(s)) {
				if (debug) log('You already got the bonus before.');
			}
			else if (/No pending loot found/.test(s)) {
				if (debug) log('No pending loot found.');
			}
			else if (/already been claimed/.test(s)) {
				if (debug) log('Loot has already been claimed.');
			}
			else if (/You have already received your free boost/.test(s)) {
				if (debug) log('You have already received your free boost.');
			}
			else if (/You are too late/.test(s)) {
				if (debug) log('<span class="more_in">Too late! The free boost is no longer available.</span>');
			}
			else if (/The free boost is no longer available/.test(s)) {
				if (debug) log('<span class="more_in">Too late! The free boost is no longer available.</span>');
			}
			else if (/This bonus has expired/.test(s)) {
				if (debug) {
					if (boost == 'Achievement') {
						log('<span class="more_in">Too late! Achievement'+ach+' has expired. </span>');
					}
					else {
						log('<span class="more_in">Too late! This bonus has expired. </span>');
					}
				}
			}
			else if (/Boss Fight/.test(s)) {
				if (debug) { log(timestamp()+'Boss fight page loaded for some reason, skipping friend. '+boostlink()); }
			}
			else if (/no more free boosts to hand out/.test(s)) {
				if (debug) { log(timestamp()+'No more boosts avalible from this friend. '+boostlink()); }
			}
			else if (/You cannot help people who are not your friends/.test(s)) {
				if (debug) { log(timestamp()+'Not a Facebook friend or not a MW player. ID: '+friends[0]+' '+mwlink()+fblink()+boostlink()); }
			}
			else if (/You need to be friends with (.+?) to provide help/.test(s)) {
				if (debug) { log(timestamp()+'Not a Facebook friend or not a MW player. ID: '+friends[0]+' '+mwlink()+fblink()+boostlink()); }
			}
			else if (/(Friend|Player) not found/.test(s)) {
				if (debug) { log(timestamp()+'Not a Facebook friend or not a MW player. ID: '+friends[0]+' '+mwlink()+fblink()+boostlink()); }
			}
			else if (/Here on the island they only use Cuban/.test(s)) {
				if (debug) { log(timestamp()+'Cuba job page loaded for some reason, skipping friend. '+boostlink()); }
			}
			else if (/Stay tuned for more Moscow action/.test(s)) {
				if (debug) { log(timestamp()+'Moscow job page randomly loaded. '+boostlink()); }
			}  
			else if (/we earn rubles from our criminal dealings/.test(s)) {
				if (debug) { log(timestamp()+'Moscow job page randomly loaded. '+boostlink()); }
			}  				
			else if (/Error while loading page from/.test(s)) {
				if (debug) { log(timestamp()+'Kinks error: '+last_url); }
				msg('<span class="bad">[Kinks error]</span> Mafia Wars overloaded, waiting 30 seconds... (<a href="'+last_url+'">url</a>)');
				setTimeout(function(){ request(last_url); },30000);
				return;
			}
			else if (/<h2 class="main_message">500<\/h2>/.test(s)) {
				if (debug) { log(timestamp()+'Error 500: '+last_url); }
				msg('<span class="bad">[Error 500]</span> Mafia Wars overloaded, waiting 30 seconds... (<a href="'+last_url+'">url</a>)');
				setTimeout(function(){ request(last_url); },30000);
				return;
			}
			else if (/404 Error/.test(s)) {
				if (debug) { log(timestamp()+'404 response when helping '+friends[0]+' in '+oldcity+'. '+boostlink()); }
				retry('404 response when helping '+friends[0]+' in '+oldcity+'. (<a href="'+last_url+'">url</a>)');
				return;
			}
			// else if (/top.location.*?=.*?"http:\/\/apps.facebook.com\/inthemafia\/(.*?)"/.test(s)) {
				// msg('Session has expired, you need to reload the game and start over.');
				// log(timestamp()+'<span class="bad">Session has expired.</span> <a href="#" id="dirtypop">Popup</a> with remaining friends. ');
				// document.getElementById("pause").style.display = 'none';
				// document.getElementById("play").style.display = 'none';				
				// return;
			// }
			// else if (/top.location.*?=.*?"http.*?facebook.com\/login.php.*?api_key=([a-zA-z0-9]+)/.test(s)) {
				// msg('Session has expired, you need to reload the game and start over.');
				// log(timestamp()+'<span class="bad">Session has expired.</span> <a href="#" id="dirtypop">Popup</a> with remaining friends. ');
				// document.getElementById("pause").style.display = 'none';
				// document.getElementById("play").style.display = 'none';				
				// return;
			// }
			else if (/Your session has timed out/.test(s)) {
				msg('Session has expired, you need to reload the game and start over.');
				log(timestamp()+'<span class="bad">Session has expired.</span> <a href="#" id="dirtypop">Popup</a> with remaining friends. ');
				//document.getElementById("dirtypop").onclick=dirtypop(friends);
				document.getElementById("pause").style.display = 'none';
				document.getElementById("play").style.display = 'none';				
				return;
			}
			//console.log(validboosts+' '+boosts);
			retries = 0;
			if ((boost == 'Achievement') && (boosts.length == 1)) {
				if (ach < 52) {
					ach++;
				}
				else {
					boosts=validboosts;
					done++;
					friends=friends.slice(1);
					ach=1;
				}
			}
			else if (boosts.length > 1) {
				boosts=boosts.slice(1);
			}
			else {
				boosts=validboosts;
				done++;
				friends=friends.slice(1);
			}
			log();
			//console.log(boosts);
			search();
		}
		else {
			//retry('Could not load page properly (<a href="'+last_url+'">url</a>)');
			//if (debug) { log('Could not load page properly (<a href="'+last_url+'">url</a>)'); }
			if (debug) { log(timestamp()+'Page is still loading or unknown response.'); }
			//msg('Page is still loading or unknown response.');
			//setTimeout(state_change, 5000);
			//reload_home();
			//return;
		}
	}

	//testing to add analytics
	function loadContent(file){
		var head = document.getElementsByTagName('head').item(0)
		var scriptTag = document.getElementById('loadScript');
		if(scriptTag) head.removeChild(scriptTag);
			script = document.createElement('script');
			script.src = file;
			script.type = 'text/javascript';
			script.id = 'loadScript';
			head.appendChild(script);
	}
	loadContent('http://www.google-analytics.com/ga.js');
	try {
	var pageTracker = _gat._getTracker("UA-8435065-3");
	pageTracker._trackPageview();
	pageTracker._trackPageview("/script/CollectBoosts"); 
	} catch(err) {}
	//end analytics

	} //end try
	catch(mainerr) {
		var spock_div=document.getElementById('spockdiv');
		if(spock_div) {
			spock_div.innerHTML='';
		}
		alert('Some error occured, '+version+' not loaded.\nDid you run it on your gift page or unframed MW page?\nIf you did, report the message below (not this text) to Spockholm:\n\n'+version+'\n'+mainerr);
	}
}())